require 'rubygems'
require 'errfix'

# Uses the errfix gem to generate random walks through the states (messages) provided
# in a csv table (in a format similar to the following example)

=begin
  Start/End,GET,NOT_FOUND,POST,OK,HEAD
  GET,,HTTPNotFound,HTTPPost,HTTPOk,HTTPHead
  NOT_FOUND,HTTPGet,,HTTPPost,HTTPOk,HTTPHead
  POST,HTTPGet,HTTPNotFound,,HTTPOk,HTTPHead
  OK,HTTPGet,HTTPNotFound,HTTPPost,,HTTPHead
  HEAD,HTTPGet,HTTPNotFound,HTTPPost,HTTPOk,
=end

# in CAPS are the state machine labels. The other elements are MuSLBuilder component
# message class names

# takes a musl_builder properties file as the first argument, the path to a new
# musl_builder properties file as the second argument, and the message/state csv file
# as the third argument

# the same arguments (first and third) will generate a different output file (second argument)
# each time it is run from the command-line

# the newly output properties file will contain a 'messages' parameter consisting
# of a random walk through the message classes provided in the csv file

# example
# ruby state_fuzz_generator.rb properties/HTTP.properties properties/HTTP_fuzz.properties csv/HTTP.csv

# the resulting properties file can be passed as an argument to muslbuilder.rb to create
# a new scenario in the Mu Scenario Language

class StateFuzzGenerator
  def initialize(input_properties_file, output_properties_file, csv_file)
    arr = []
    f = File.open(input_properties_file, "r")
    f.each_line do |line|
       if !line.include?("messages=")
          arr.push line
       end
    end    

    # generate a random walk through the message components list
    steps = ""
    model = StateModelCreator.new.load_table(csv_file)
    model.create_dot_graph.output("state_fuzz_generator.dot")
    walk = model.random_walk("GET") # FIXME: use the first step in the csv file
    walk.steps.each do | step |
      s = step.to_s.split(",")
      s2 = s[1].split(" ")
      puts s2[0]
      steps = steps + s2[0] + ","
    end
    steps = steps[0, steps.length - 1] # lose the last comma

    msg_line = "messages=#{steps}"
    arr.push msg_line

    # write out the output_properties file with the new messages parameter
    new_props = ""
    arr.each do | a |
      new_props = new_props + a + "\n"
    end
    new_props.chomp # lose the last new line

    File.open(output_properties_file, 'w') do |f2|
     f2.puts new_props
    end

  end
end


if $0 == __FILE__
  if ARGV[2].nil?  # if no properties file ... use a hardcoded array for testing
    puts "Usage: <input_properties_file> <output_properties_file> <state_table.csv file>"
  else
    $sfg = StateFuzzGenerator.new(ARGV[0], ARGV[1], ARGV[2]) 
  end
end